using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Net;
using System.Xml.Serialization;
using System.IO;
using System.Text;
using System.Xml;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
using System.Timers;

using MediaPortal.GUI.Library;
using MediaPortal.Dialogs;
using MediaPortal.Util;
using MediaPortal.Localisation;
using MediaPortal.Configuration;
using MediaPortal.Player;
using MediaPortal.Playlists;

using YahooMusicEngine;
using YahooMusicEngine.OnlineDataProvider;
using YahooMusicEngine.Services;
using YahooMusicEngine.Entities;
using YahooMusicEngine.Locale;


namespace YahooMusicPlugin
{
  public class YahooMusicGUI : YahooMusicGUIBase, ISetupForm 
  {

    #region MapSettings class
    [Serializable]
    public class MapSettings
    {
      protected int _SortBy;
      protected int _ViewAs;
      protected bool _SortAscending;

      public MapSettings()
      {
        // Set default view
        _SortBy = 0;
        _ViewAs = (int)View.List;
        _SortAscending = true;
      }

      [XmlElement("SortBy")]
      public int SortBy
      {
        get { return _SortBy; }
        set { _SortBy = value; }
      }

      [XmlElement("ViewAs")]
      public int ViewAs
      {
        get { return _ViewAs; }
        set { _ViewAs = value; }
      }

      [XmlElement("SortAscending")]
      public bool SortAscending
      {
        get { return _SortAscending; }
        set { _SortAscending = value; }
      }
    }
    #endregion

    #region Base variables

    #endregion

    enum View
    {
      List = 0,
      Icons = 1,
      BigIcons = 2,
      Albums = 3,
      PlayList = 4,
      Filmstrip = 5
    }

    #region locale vars

    private WebClient Client = new WebClient();
    private Queue downloaQueue = new Queue();
    private Stack NavigationStack = new Stack();
    private System.Timers.Timer updateStationLogoTimer = new System.Timers.Timer(1 * 1000);
    private DownloadFileObject curentDownlodingFile;
    MapSettings mapSettings = new MapSettings();

    List<VideoResponse> curentVideoList = new List<VideoResponse>();
    List<CategoryEntity> curentCategories = new List<CategoryEntity>();
    List<ArtistResponse> curentArtists = new List<ArtistResponse>();

    //private StationSort.SortMethod curSorting = StationSort.SortMethod.name;
    CategoryTreeService catserv = new CategoryTreeService();
    //CategoryEntity lastItems = null;
    VideosForACategoryService videolist = new VideosForACategoryService();


    #endregion

    #region skin connection
    [SkinControlAttribute(50)]
    protected GUIFacadeControl listControl = null;
    [SkinControlAttribute(2)]
    protected GUISortButtonControl sortButton = null;
    [SkinControlAttribute(4)]
    protected GUIButtonControl homeButton = null;
    [SkinControlAttribute(3)]
    protected GUIButtonControl btnSwitchView = null;
    [SkinControlAttribute(5)]
    protected GUIButtonControl searchButton = null;
    [SkinControlAttribute(6)]
    protected GUIButtonControl searchArtistButton = null;
    [SkinControlAttribute(7)]
    protected GUIButtonControl btnPlayList = null;
    [SkinControlAttribute(8)]
    protected GUIButtonControl btnNowPlaying = null;
    [SkinControlAttribute(9)]
    protected GUIButtonControl btnCountry = null;

    #endregion


    public YahooMusicGUI()
    {
      GetID = GetWindowId();
      updateStationLogoTimer.AutoReset = true;
      updateStationLogoTimer.Enabled = false;
      updateStationLogoTimer.Elapsed += new ElapsedEventHandler(OnDownloadTimedEvent);
      Client.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadLogoEnd);
      GUIWindowManager.Receivers += new SendMessageHandler(GUIWindowManager_Receivers);
 
    }

    void GUIWindowManager_Receivers(GUIMessage message)
    {
      if (message.Message == GUIMessage.MessageType.GUI_MSG_PLAY_ITEM)
      {
        if (message.Object != null)
        {
          string strMessage = message.Object as string;
          if (!string.IsNullOrEmpty(strMessage))
          {
            string clipid = string.Empty;
            string spaceId = string.Empty;
            XmlDocument document = new XmlDocument();
            document.LoadXml(strMessage);
            XmlNode strType = document.SelectSingleNode("invoke/arguments/string");
            if (strType != null && strType.InnerText == "itemBegin")
            {
              XmlNodeList propetynode = document.SelectNodes("invoke/arguments/object/property");
              foreach (XmlNode node in propetynode)
              {
                if (node.Attributes["id"].Value == "clipid")
                {
                  clipid = node.SelectSingleNode("string").InnerText;
                  clipid = clipid.Substring(1);
                }
                if (node.Attributes["id"].Value == "spaceId")
                {
                  spaceId = node.SelectSingleNode("string").InnerText;
                }
              }
              VideoByIdService ser = new VideoByIdService();
              ser.Id = clipid;
              provider.GetData(ser);
              if (ser.Items.Count > 0)
              {
                Log.Debug("Palying item {0} with spaceid {1} Title {2}", ser.Items[0].Video.Id, spaceId, ser.Items[0].Video.Title);
                btnNowPlaying.Disabled = false;
                SetLabels(ser.Items[0], "NowPlaying");
                MessageGUI.NowPlaying = ser.Items[0];
                GUIPropertyManager.SetProperty("#Play.Current.Title", FormatTitle(MessageGUI.NowPlaying));
                DownloadImage(ser.Items[0], null);
              }
            }
            else if (strType != null && strType.InnerText == "itemEnd")
            {
              btnNowPlaying.Disabled = true;
              ClearLabels("NowPlaying");
            }
          }
        }
      }
    }

    #region ISetupForm Members
    // return name of the plugin
    public string PluginName()
    {
      return "Yahoo Music Videos";
    }
    // returns plugin description
    public string Description()
    {
      return "Plugin for expose the Yahoo Music contents";
    }
    // returns author
    public string Author()
    {
      return "Dukus";
    }
    // shows the setup dialog
    public void ShowPlugin()
    {
      SetupForm setup = new SetupForm();
      setup.ShowDialog();
    }
    // enable / disable
    public bool CanEnable()
    {
      return true;
    }
    // returns the unique id again
    public int GetWindowId()
    {
      return 27050;
    }
    // default enable?
    public bool DefaultEnabled()
    {
      return true;
    }
    // has setup gui?
    public bool HasSetup()
    {
      return true ;
    }
    // home button
    public bool GetHome(out string strButtonText, out string strButtonImage,
      out string strButtonImageFocus, out string strPictureImage)
    {
      // set the values for the buttom
      strButtonText = "Yahoo Music Videos";

      // no image or picture
      strButtonImage = String.Empty;
      strButtonImageFocus = String.Empty;
      strPictureImage = String.Empty;

      return true;
    }
    // init the skin
    public override bool Init()
    {
      _setting.Load();
      provider.AppId = "DeUZup_IkY7d17O2DzAMPoyxmc55_hTasA--";
      provider.SharedSecret = "d80b9a5766788713e1fadd73e752c7eb";
      provider.Token = _setting.Token;
      provider.OnError += new ServiceProvider.OnErrorEventHandler(provider_OnError);
      provider.Init();
      if (string.IsNullOrEmpty(provider.CurentUser.Ymid))
      {
        _setting.Token = string.Empty;
        _setting.Save();
      }
      return Load(GUIGraphicsContext.Skin + @"\yahoomusicmain.xml");
    }

    void provider_OnError(Exception ex)
    {
      Log.Error("Yahoo music error :{2} \n {0} \n {1} ", ex.Message, ex.StackTrace, provider.ErrorMessage);
    }
     //do the init before page load
    protected override void OnPageLoad()
    {
      updateStationLogoTimer.Enabled = true;
      GUIPropertyManager.SetProperty("#nowplaying", " ");
      if (MessageGUI.Item != null)
      {
        CategoryEntity cat = MessageGUI.Item as CategoryEntity;
        UpdateListing(cat);
      }
      else
      {
        if (NavigationStack.Count == 0)
        {
          ClearLabels("Curent");
          ClearLabels("NowPlaying");
          GUIPropertyManager.SetProperty("#header.label", GUILocalizeStrings.Get(127052));
          provider.SetLocale(_setting.Locale);
          InitList();
        }
        else
        {
          DoBack();
          GUIControl.FocusControl(GetID, listControl.GetID);
        }
      }
      
      base.OnPageLoad();
    }

    private void InitList()
    {
      provider.GetData(catserv);
      UpdateListing(null);
    }
    // remeber the selection on page leave
    protected override void OnPageDestroy(int new_windowId)
    {
      SaveListState(false);
      base.OnPageDestroy(new_windowId);
    }
    //// do the clicked action
    protected override void OnClicked(int controlId, GUIControl control, Action.ActionType actionType)
    {
      ////
      //// look for button pressed
      ////
      //// record ?
      if (actionType == Action.ActionType.ACTION_RECORD)
      {
        //ExecuteRecord();
      }
      else if (control == btnSwitchView)
      {
        switch ((View)mapSettings.ViewAs)
        {
          case View.List:
            mapSettings.ViewAs = (int)View.Icons;
            break;
          case View.Icons:
            mapSettings.ViewAs = (int)View.BigIcons;
            break;
          case View.BigIcons:
            mapSettings.ViewAs = (int)View.Albums;
            break;
          case View.Albums:
            mapSettings.ViewAs = (int)View.Filmstrip;
            break;
          case View.Filmstrip:
            mapSettings.ViewAs = (int)View.List;
            break;
        }
        ShowPanel();
        GUIControl.FocusControl(GetID, control.GetID);
      }
      else if (control == listControl)
      {
        // execute only for enter keys
        if (actionType == Action.ActionType.ACTION_SELECT_ITEM)
        {
          // station selected
          DoListSelection();
        }
      }
      else if (control == sortButton)
      {
        //sort button selected
        OnShowSortOptions();
      }
      else if (control == searchButton)
      {
        DoSearch();
        GUIControl.FocusControl(GetID, listControl.GetID);
      }
      else if (control == homeButton)
      {
        DoHome();
        GUIControl.FocusControl(GetID, listControl.GetID);
      }
      else if (control == searchArtistButton)
      {
        DoSearchArtist();
        GUIControl.FocusControl(GetID, listControl.GetID);
      }
      else if (control == btnPlayList)
      {
        GUIWindowManager.ActivateWindow((int)GUIWindow.Window.WINDOW_VIDEO_PLAYLIST);
      }
      else if (control == btnNowPlaying)
      {
        GUIWindowManager.ActivateWindow(27052);
      }
      else if (control == btnCountry)
      {
        SelectLang();
      }
      base.OnClicked(controlId, control, actionType);
    }

    private void DoSearchArtist()
    {
      string searchString = "";

      // display an virtual keyboard
      VirtualKeyboard keyboard = (VirtualKeyboard)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_VIRTUAL_KEYBOARD);
      if (null == keyboard) return;
      keyboard.Reset();
      keyboard.Text = searchString;
      keyboard.DoModal(GetWindowId());
      if (keyboard.IsConfirmed)
      {
        // input confirmed -- execute the search
        searchString = keyboard.Text;
      }

      if ("" != searchString)
      {
        SearchForArtistsService searcher = new SearchForArtistsService();
        searcher.Keyword = searchString;
        searcher.Count = _setting.ItemCount;
        provider.GetData(searcher);
        if (searcher.SpellResults.Count > 0)
        {
          GUIDialogSelect2 dlg = (GUIDialogSelect2)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_SELECT2);
          if (dlg == null)
            return;
          dlg.Reset();
          dlg.SetHeading(127087); // menu
          foreach (SpellResultEntity res in searcher.SpellResults)
          {
            dlg.Add(res.Suggestion);
          }
          dlg.DoModal(GetID);
          if (dlg.SelectedLabel == -1)
            return;
          foreach (SpellResultEntity res in searcher.SpellResults)
          {
            if (res.Suggestion == dlg.SelectedLabelText)
            {
              searcher.Keyword = res.Suggestion;
              searcher.Spelltoken = res.Token;
            }
          }
        }
        provider.GetData(searcher);
        if (searcher.Items.Count > 0)
        {
          SaveListState(true);
          addArtists(searcher.Items);
          UpdateGui();
        }
        else
        {
          Err_message(127086);
        }
      }
    }


    private void DoHome()
    {
          GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
          VideosForGivenPublishedListService pub = new VideosForGivenPublishedListService();
          pub.Count = _setting.ItemCount;
          if (dlg == null)
            return;
          dlg.Reset();
          dlg.SetHeading(127051); // menu
          dlg.AddLocalizedString(127052); // cat : genre
          dlg.AddLocalizedString(127053); // cat : era
          dlg.AddLocalizedString(127054); // cat : theme
          dlg.AddLocalizedString(127055); // popular
          dlg.AddLocalizedString(127056); // new 
          dlg.AddLocalizedString(127058); // video station
          if (!string.IsNullOrEmpty(_setting.Favorites))
          {
            dlg.AddLocalizedString(127057); // Favorites
          }
          dlg.DoModal(GetID);
          if (dlg.SelectedId == -1)
            return;
          GUIPropertyManager.SetProperty("#header.label", GUILocalizeStrings.Get(dlg.SelectedId));
          curentCategories.Clear();
          curentVideoList.Clear();
          switch (dlg.SelectedId)
          {
            case 127052:
              catserv.Type = CategoryTreeTypes.genre;
              provider.GetData(catserv);
              UpdateListing(null);
              break;
            case 127053:
              catserv.Type = CategoryTreeTypes.era;
              provider.GetData(catserv);
              UpdateListing(null);
              break;
            case 127054:
              catserv.Type = CategoryTreeTypes.theme;
              provider.GetData(catserv);
              UpdateListing(null);
              break;
            case 127055:
              pub.Id = "popular";
              provider.GetData(pub);
              UpdatesVideos(pub, true);
              break;
            case 127056:
              pub.Id = "new";
              provider.GetData(pub);
              UpdatesVideos(pub, true);
              break;
            case 127058: // video station
              {
                VideoStationsForAPublishedListService vs = new VideoStationsForAPublishedListService();
                vs.Id = "43643359";
                provider.GetData(vs);
                SaveListState(true);
                addStation(vs.Items);
                UpdateGui();
              }
              break;
            case 127057:
              VideoByIdService vids = new VideoByIdService();
              vids.Id = _setting.Favorites;
              provider.GetData(vids,false);
              if (vids.Items.Count > 0)
              {
                SaveListState(true);
                addVideos(vids.Items);
                UpdateGui();
              }
              else
              {
                Err_message(127086);
              }

              break;
          }

    }


    //// override action responses
    public override void OnAction(Action action)
    {
      if (action.wID == Action.ActionType.ACTION_PREVIOUS_MENU)
      {
        if (listControl.Focus)
        {
          if (NavigationStack.Count > 0)
          {
            DoBack();
            return;
          }
        }
      }

      if (action.wID == Action.ActionType.ACTION_PARENT_DIR)
      {
        GUIListItem item = listControl[0];

        if ((item != null) && item.IsFolder && (item.Label == ".."))
        {
          DoBack();
          return;
        }
      }
      UpdateGui();
      base.OnAction(action);
    }
    // do regulary updates
    public override void Process()
    {
      // update the gui
      UpdateGui();
    }

    protected void OnShowSortOptions()
    {
      //GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
      //if (dlg == null) return;
      //dlg.Reset();
      //dlg.SetHeading(25653); // Sort options

      //dlg.AddLocalizedString(25654); // name
      //dlg.AddLocalizedString(25655); // bitrate
      //// set the focus to currently used sort method
      //dlg.SelectedLabel = (int)curSorting;

      //// show dialog and wait for result
      //dlg.DoModal(GetID);
      //if (dlg.SelectedId == -1) return;

      //switch (dlg.SelectedLabel)
      //{
      //  case 0:
      //    curSorting = StationSort.SortMethod.name;
      //    sortButton.Label = GUILocalizeStrings.Get(25654);
      //    break;
      //  case 1:
      //    curSorting = StationSort.SortMethod.bitrate;
      //    sortButton.Label = GUILocalizeStrings.Get(25655);
      //    break;
      //  default:
      //    curSorting = StationSort.SortMethod.name;
      //    sortButton.Label = GUILocalizeStrings.Get(25654);
      //    break;
      //}

      //sortButton.IsAscending = mapSettings.SortAscending;
      //UpdateList();
    }
 
    #endregion
    #region helper func's

    private void DoListSelection()
    {
      GUIWaitCursor.Show();
      GUIListItem selectedItem = listControl.SelectedListItem;
      if (selectedItem != null)
      {
        if (selectedItem.Label != "..")
        {

          CategoryEntity cats = selectedItem.MusicTag as CategoryEntity;
          if (cats != null)
          {
            UpdateListing(cats);
          }
          ArtistResponse art = selectedItem.MusicTag as ArtistResponse;
          if (art != null)
          {
            UpdateArtistListing(art);
          }
          VideoResponse vid = selectedItem.MusicTag as VideoResponse;
          if (vid != null)
          {
            DoPlay(vid);
          }
          StationResponse st = selectedItem.MusicTag as StationResponse;
          if (st != null)
          {
            UpdateStationListing(st);
          }
          VideoServiceBase serv = selectedItem.MusicTag as VideoServiceBase;
          if (serv != null)
          {
            provider.GetData(serv);
            UpdatesVideos(serv,true);
          }
        }
        else
        {
          DoBack();
        }
      }
      GUIWaitCursor.Hide();
      //throw new Exception("The method or operation is not implemented.");
    }

    private void UpdateArtistListing(ArtistResponse art)
    {
      SaveListState(true);      
      updateStationLogoTimer.Enabled = false;
      downloaQueue.Clear();

      GUIListItem item = new GUIListItem();
      // and add station name & bitrate
      item.Label = "..";
      item.IsFolder = true;
      MediaPortal.Util.Utils.SetDefaultIcons(item);
      item.MusicTag = curentArtists;
      listControl.Add(item);

      ArtistByIdService serv = new ArtistByIdService();
      serv.Id = art.Artist.Id;
      provider.GetData(serv);
      if (serv.Items.Count > 0)
        addVideos(serv.Items[0]);
      UpdateGui();
      updateStationLogoTimer.Enabled = true ;
    }

    private void UpdateStationListing(StationResponse art)
    {
      SaveListState(true);
      updateStationLogoTimer.Enabled = false;
      downloaQueue.Clear();

      GUIListItem item = new GUIListItem();
      // and add station name & bitrate
      item.Label = "..";
      item.IsFolder = true;
      MediaPortal.Util.Utils.SetDefaultIcons(item);
      //item.MusicTag = curentArtists;
      listControl.Add(item);

      VideosForACategoryStationService serv = new VideosForACategoryStationService();
      serv.Category = art.Station.Id;
      serv.Count = _setting.ItemCount;
      provider.GetData(serv);
      if (serv.Items.Count > 0)
        addVideos(serv.Items);
      UpdateGui();
      updateStationLogoTimer.Enabled = true;
    }

    private void DoPlayAll(List<VideoResponse> vids)
    {
      if (vids != null)
      {
        VideoPlayer player = new VideoPlayer("");
        player.AutoStart = true;
        player.Bandwidth = _setting.Bandwith;
        player.Ympsc = provider.Locale.Ympsc;
        player.EID = provider.Locale.EID;
        player.VideoIds.Clear();
        foreach (VideoResponse vid in vids)
        {
          if (!string.IsNullOrEmpty(vid.Video.Id))
          {
            player.VideoIds.Add(vid.Video.Id);
          }
        }
        Log.Debug("Play: " + player.VideoPlayerUrl);
        g_Player.Play(player.VideoPlayerUrl);
        g_Player.ShowFullScreenWindow();

      }
    }

    private void DoSearch()
    {
      string searchString = "";

      // display an virtual keyboard
      VirtualKeyboard keyboard = (VirtualKeyboard)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_VIRTUAL_KEYBOARD);
      if (null == keyboard) return;
      keyboard.Reset();
      keyboard.Text = searchString;
      keyboard.DoModal(GetWindowId());
      if (keyboard.IsConfirmed)
      {
        // input confirmed -- execute the search
        searchString = keyboard.Text;
      }

      if ("" != searchString)
      {
        SearchForVideosService searcher = new SearchForVideosService();
        searcher.Keyword = searchString;
        searcher.Count = _setting.ItemCount;
        provider.GetData(searcher);
        if (searcher.SpellResults.Count > 0)
        {
          GUIDialogSelect2 dlg = (GUIDialogSelect2)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_SELECT2);
          if (dlg == null)
            return;
          dlg.Reset();
          dlg.SetHeading(127087); // menu
          foreach (SpellResultEntity res in searcher.SpellResults)
          {
            dlg.Add(res.Suggestion);
          }
          dlg.DoModal(GetID);
          if (dlg.SelectedLabel == -1)
            return;
          foreach (SpellResultEntity res in searcher.SpellResults)
          {
            if (res.Suggestion == dlg.SelectedLabelText)
            {
              searcher.Keyword = res.Suggestion;
              searcher.Spelltoken = res.Token;
            }
          }
        }
        provider.GetData(searcher);
        if (searcher.Items.Count > 0)
        {
          UpdatesVideos(searcher, true);
        }
        else
        {
          Err_message(127086);
        }
      }
    }
    
    private void DoBack()
    {
      if (NavigationStack.Count > 0)
      {
        GUIControl.ClearControl(GetID, listControl.GetID);
        NavigationObject obj = NavigationStack.Pop() as NavigationObject;
        obj.SetItems(listControl);
        listControl.SelectedListItemIndex = obj.Position;
        GUIPropertyManager.SetProperty("#header.label", obj.Title);
      }
    }
    
    //public void UpdateList()
    //{
   
    //}

    void ShowPanel()
    {
      int itemIndex = listControl.SelectedListItemIndex;
      if (mapSettings.ViewAs == (int)View.BigIcons)
      {
        listControl.View = GUIFacadeControl.ViewMode.LargeIcons;
      }
      else if (mapSettings.ViewAs == (int)View.Albums)
      {
        listControl.View = GUIFacadeControl.ViewMode.AlbumView;
      }
      else if (mapSettings.ViewAs == (int)View.Icons)
      {
        listControl.View = GUIFacadeControl.ViewMode.SmallIcons;
      }
      else if (mapSettings.ViewAs == (int)View.List)
      {
        listControl.View = GUIFacadeControl.ViewMode.List;
      }
      else if (mapSettings.ViewAs == (int)View.Filmstrip)
      {
        listControl.View = GUIFacadeControl.ViewMode.Filmstrip;
      }
      else if (mapSettings.ViewAs == (int)View.PlayList)
      {
        listControl.View = GUIFacadeControl.ViewMode.Playlist;
      }

      if (itemIndex > -1)
      {
        GUIControl.SelectItemControl(GetID, listControl.GetID, itemIndex);
      }
     
    }

    /// <summary>
    /// Called when [show context menu].
    /// </summary>
    protected override void OnShowContextMenu()
    {
      GUIListItem selectedItem = listControl.SelectedListItem;
      VideoResponse vidItem = null;
      GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
      if (dlg == null)
        return;
      dlg.Reset();
      dlg.SetHeading(498); // menu
      if (curentVideoList.Count > 0)
      {
        dlg.AddLocalizedString(127072); //play all
      }

      if (selectedItem != null)
      {
        vidItem = selectedItem.MusicTag as VideoResponse;
        if (vidItem != null && !string.IsNullOrEmpty(vidItem.Artist.Id))
        {
          dlg.AddLocalizedString(127075); // info
          dlg.AddLocalizedString(127082);// add to playlist
          dlg.AddLocalizedString(127080);// all videos from artis
          dlg.AddLocalizedString(127084); // similar artist
          dlg.AddLocalizedString(127085); // similar videos
          if (!_setting.Favorites.Contains(vidItem.Video.Id))
          {
            dlg.AddLocalizedString(127089); //add to favorites
          }
          else
          {
            dlg.AddLocalizedString(127093); //remove from favorites
          }
        }
      }
      dlg.AddLocalizedString(127073);// option

      dlg.DoModal(GetID);
      if (dlg.SelectedId == -1)
        return;
      switch (dlg.SelectedId)
      {
        case 127072: //playall
          DoPlayAll(curentVideoList);
          break;
        case 127073: //option
          DoOption();
          break;
        case 127075: //info
          DoInfo();
          break;
        case 127080: // all videos from artis
          ArtistByIdService artid = new ArtistByIdService();
          artid.Id = vidItem.Artist.Id;
          provider.GetData(artid);
          if (artid.Items.Count > 0)
          {
            SaveListState(true);
            addVideos(artid.Items[0]);
          }
          else
          {
            Err_message(127086);
          }
          break;
        case 127082: //add to playlist
          AddItemToPlayList(selectedItem);
          break;
        case 127084: // similar artist
          {
            SimilarArtistsService similaart = new SimilarArtistsService();
            similaart.Id = vidItem.Artist.Id;
            provider.GetData(similaart);
            if (similaart.Items.Count > 0)
            {
              SaveListState(true);
              addArtists(similaart.Items);
            }
            else
            {
              Err_message(127086);
            }
          }
          break;
        case 127085:  // similar videos
          {
            SimilarVideosService similarvid = new SimilarVideosService();
            similarvid.Id = vidItem.Video.Id;
            //similarvid.Count = _setting.ItemCount;
            provider.GetData(similarvid);
            if (similarvid.Count > 0)
            {
              UpdatesVideos(similarvid, true);
              //SaveListState(true);
              //addVideos(similarvid.Items);
            }
            else
            {
              Err_message(127086);
            }
          }
          break;
        case 127089:  // add to favorites
          {
            //UserFavoriteVideosService fav = new UserFavoriteVideosService();
            //fav.Ymid = provider.CurentUser.Ymid;
            //fav.Ids = vidItem.Video.Id;
            //provider.PostData(fav);
            _setting.Favorites += vidItem.Video.Id + ",";
          }
          break;
        case 127093:  // add to favorites
          {
            _setting.Favorites = _setting.Favorites.Replace(vidItem.Video.Id + ",", string.Empty);
          }
          break;
      }
    }

    private void DoInfo()
    {
      YahooMusicInfoGUI guiInfo = (YahooMusicInfoGUI)GUIWindowManager.GetWindow(27051);
      guiInfo.InfoItem = listControl.SelectedListItem.MusicTag as VideoResponse;
      guiInfo.provider = this.provider;
      GUIWindowManager.ActivateWindow(27051);
    }

    /// <summary>
    /// Does the option.
    /// </summary>
    private void DoOption()
    {
      GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
      if (dlg == null)
        return;
      dlg.Reset();
      dlg.SetHeading(127073); // menu
      dlg.AddLocalizedString(127074); //language
      if (_setting.ShowPlayableOnly)
      {
        dlg.AddLocalizedString(127091); // show all items
      }
      else
      {
        dlg.AddLocalizedString(127092); // show playeble only
      }
      dlg.DoModal(GetID);
      if (dlg.SelectedId == -1)
        return;
      switch (dlg.SelectedId)
      {
        case 127074: //language
          SelectLang();
          break;
        case 127091: // show all items
          _setting.ShowPlayableOnly = false;
          break;
        case 127092:  // show playeble only
          _setting.ShowPlayableOnly = true;
          break;

      }
    }

    private void SelectLang()
    {
      GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
      if (dlg == null)
        return;
      dlg.Reset();
      dlg.SetHeading(127073); // menu
      foreach (LocaleEntity en in provider.AvaiableLocales)
      {
        GUIListItem item = new GUIListItem();
        item.Label = en.Locale;
        item.IconImage = GUIGraphicsContext.Skin + @"\media\" + en.ApiHost + ".png";
        dlg.Add(item);
      }
      dlg.DoModal(GetID);
      if(dlg.SelectedLabel==-1)
        return;
      provider.ClearCache();
      provider.SetLocaleByName(dlg.SelectedLabelText);
      _setting.Locale = provider.Locale.ApiHost;
      InitList();
    }


    /// <summary>
    /// Adds to favorites.
    /// </summary>
    /// <param name="p">The station id.</param>
    private void AddToFavorites(int p)
    {
      //try
      //{
      //  FavoriteFolderUpdateRequest req = new FavoriteFolderUpdateRequest();
      //  req.ItemIds = new int[] { p };
      //  req.Identification = iden;
      //  websrv.Favorite_StationListAdd(req);
      //  grabber.GetData(grabber.CurentUrl, grabber.CacheIsUsed, false);
      //  UpdateList();
      //}
      //catch (Exception)
      //{
      //  Err_message(25659);
      //}
    }

    public void UpdateGui()
    {

      string textLine = string.Empty;
      View view = (View)mapSettings.ViewAs;
      bool sortAsc = mapSettings.SortAscending;
      switch (view)
      {
        case View.List:
          textLine = GUILocalizeStrings.Get(101);
          break;
        case View.Icons:
          textLine = GUILocalizeStrings.Get(100);
          break;
        case View.BigIcons:
          textLine = GUILocalizeStrings.Get(417);
          break;
        case View.Albums:
          textLine = GUILocalizeStrings.Get(529);
          break;
        case View.Filmstrip:
          textLine = GUILocalizeStrings.Get(733);
          break;
        case View.PlayList:
          textLine = GUILocalizeStrings.Get(101);
          break;

      }
      GUIControl.SetControlLabel(GetID, btnSwitchView.GetID, textLine);

    }

    void SortChanged(object sender, SortEventArgs e)
    {
      // save the new state
      mapSettings.SortAscending = e.Order != System.Windows.Forms.SortOrder.Descending;
      // update the list
      //UpdateList();
      //UpdateButtonStates();
      GUIControl.FocusControl(GetID, ((GUIControl)sender).GetID);
    }

    #endregion

    #region download manager


    private string DownloadImage(VideoResponse vid, GUIListItem listitem)
    {
      return DownloadImage(vid.Image.Url, listitem);
    }

    private string DownloadImage(string Url)
    {
      //string localFile = GetLocalImageFileName(Url);
      //if (!File.Exists(localFile) && !string.IsNullOrEmpty(Url))
      //{
      //  downloaQueue.Enqueue(new DownloadFileObject(localFile, Url));
      //}
      return DownloadImage(Url, null);
    }

    private string DownloadImage(string Url, GUIListItem listitem)
    {
      string localFile = GetLocalImageFileName(Url);
      if (!File.Exists(localFile) && !string.IsNullOrEmpty(Url))
      {
        downloaQueue.Enqueue(new DownloadFileObject(localFile, Url, listitem));
      }
      return localFile;
    }
    
    private void OnDownloadTimedEvent(object source, ElapsedEventArgs e)
    {
      if (!Client.IsBusy && downloaQueue.Count>0)
      {
        curentDownlodingFile = (DownloadFileObject)downloaQueue.Dequeue();
        Client.DownloadFileAsync(new Uri(curentDownlodingFile.Url), Path.GetTempPath() + @"\station.png");
      }
    }

    private void DownloadLogoEnd(object sender, AsyncCompletedEventArgs e)
    {
      if (e.Error == null)
      {
        File.Copy(Path.GetTempPath() + @"\station.png", curentDownlodingFile.FileName, true);
        if (curentDownlodingFile.ListItem != null && File.Exists(curentDownlodingFile.FileName))
        {
          curentDownlodingFile.ListItem.ThumbnailImage = curentDownlodingFile.FileName;
          curentDownlodingFile.ListItem.IconImageBig = curentDownlodingFile.FileName;
          curentDownlodingFile.ListItem.RefreshCoverArt();
        }
        UpdateGui();
      }
    }            

    #endregion

    public void UpdatesVideos(VideoServiceBase vids,bool clear)
    {
      if (clear)
        SaveListState(true);
      addVideos(vids.Items);
      if (!string.IsNullOrEmpty(vids.Description))
      {
        GUIPropertyManager.SetProperty("#header.label", vids.Description);
      }
      if (vids.Start + vids.Count < vids.Total)
      {
        GUIListItem item = new GUIListItem();
        item.Label = string.Format("[Show next page {0} - {1} ]", vids.Start + vids.Count, vids.Start + vids.Count + _setting.ItemCount);
        item.IsFolder = true;
        MediaPortal.Util.Utils.SetDefaultIcons(item);
        vids.Start += vids.Count;
        vids.Count = _setting.ItemCount;
        item.MusicTag = vids;
        listControl.Add(item);
      }
      UpdateGui();
    }

    public void UpdateListing(CategoryEntity cat)
    {
      curentArtists = null;
      updateStationLogoTimer.Enabled = false;
      downloaQueue.Clear();
      SaveListState(true);
      if (cat == null)
      {
        addCategories(catserv.Items, false);
      }
      else
      {

        //lastItems = cat;
        addCategories(cat.Childs, true);
        if (cat.VideoCount > 0)
        {
          videolist.Count = _setting.ItemCount; //cat.VideoCount;
          videolist.Category = cat.Id;
          provider.GetData(videolist);
          UpdatesVideos(videolist, false);
          //addVideos(videolist.Items);
        }
      }
      UpdateGui();
      updateStationLogoTimer.Enabled = true; 
    }

    void addCategories(List<CategoryEntity> cats,bool haveParent)
    {
      curentCategories = cats;
      if (haveParent)
      {
        GUIListItem item = new GUIListItem();
        // and add station name & bitrate
        item.Label = "..";
        item.IsFolder = true;
        MediaPortal.Util.Utils.SetDefaultIcons(item);
        //item.MusicTag = head;
        listControl.Add(item);
      }
      foreach (CategoryEntity cat in cats)
      {
        GUIListItem item = new GUIListItem();
        // and add station name & bitrate
        item.Label = cat.Name;
        item.Label2 = "";
        item.IsFolder = true;
        item.MusicTag = cat;
        MediaPortal.Util.Utils.SetDefaultIcons(item);
        listControl.Add(item);
      }
    }

    void addArtists(List<ArtistResponse> artists)
    {
      curentArtists = artists;
      updateStationLogoTimer.Enabled = false;
      downloaQueue.Clear();
      foreach (ArtistResponse art in artists)
      {
        GUIListItem item = new GUIListItem();
        // and add station name & bitrate
        item.Label = art.Artist.Name;
        item.Label2 = "";
        item.IsFolder = true;
        string imageFile = GetLocalImageFileName(provider.GetArtistImage(art.Artist.Id, 84));
        if (File.Exists(imageFile))
        {
          item.ThumbnailImage = imageFile;
          item.IconImage = "DefaultFolderBig.png";
          item.IconImageBig = imageFile;
        }
        else
        {
          MediaPortal.Util.Utils.SetDefaultIcons(item);
          DownloadImage(provider.GetArtistImage(art.Artist.Id, 84), item);
        }
        item.MusicTag = art;
        listControl.Add(item);
      }
      UpdateGui();
      updateStationLogoTimer.Enabled = true; 
    }

    void addStation(List<StationResponse> stations)
    {
      updateStationLogoTimer.Enabled = false;
      downloaQueue.Clear();
      foreach (StationResponse art in stations)
      {
        GUIListItem item = new GUIListItem();
        // and add station name & bitrate
        item.Label = art.Station.Name;
        item.Label2 = "";
        item.IsFolder = true;
        string imageFile = GetLocalImageFileName(provider.GetStationImage(art.Station.Id, 84));
        if (File.Exists(imageFile))
        {
          item.ThumbnailImage = imageFile;
          item.IconImage = "DefaultFolderBig.png";
          item.IconImageBig = imageFile;
        }
        else
        {
          MediaPortal.Util.Utils.SetDefaultIcons(item);
          DownloadImage(provider.GetStationImage(art.Station.Id, 84), item);
        }
        item.MusicTag = art;
        listControl.Add(item);
      }
      UpdateGui();
      updateStationLogoTimer.Enabled = true;
    }

    void addVideos(List<VideoResponse> vids)
    {
      curentVideoList = vids;
      foreach (VideoResponse vi in vids)
      {
        if (filterVideoContens(vi))
        {
          GUIListItem item = new GUIListItem();
          // and add station name & bitrate
          item.Label = FormatTitle(vi);
          item.Label2 = "";
          item.IsFolder = false;
          if (File.Exists(GetLocalImageFileName(vi.Image.Url)))
          {
            item.ThumbnailImage = GetLocalImageFileName(vi.Image.Url);
            item.IconImage = "defaultVideoBig.png";
            item.IconImageBig = GetLocalImageFileName(vi.Image.Url);
          }
          else
          {
            MediaPortal.Util.Utils.SetDefaultIcons(item);
            DownloadImage(vi, item);
          }
          item.Year = vi.Video.CopyrightYear;
          item.Duration = vi.Video.Duration;
          item.Rating = vi.Video.Rating;
          item.OnItemSelected += new MediaPortal.GUI.Library.GUIListItem.ItemSelectedHandler(item_OnItemSelected);
          
          DownloadImage(provider.GetArtistImage(vi.Artist.Id, 400));
          item.MusicTag = vi;
          listControl.Add(item);
        }
      }
    }

    void addVideos(ArtistResponse vids)
    {
      curentVideoList.Clear();
      foreach (VideoEntity res in vids.Videos)
      {
        VideoResponse vi = new VideoResponse();
        vi.Video = res;
        vi.Artist = vids.Artist;
        curentVideoList.Add(vi);
        if (filterVideoContens(vi))
        {
          GUIListItem item = new GUIListItem();
          // and add station name & bitrate
          item.Label = FormatTitle(vi);
          item.Label2 = "";
          item.IsFolder = false;
          item.ThumbnailImage = GetLocalImageFileName(provider.GetVideoImage(vi.Video.Id, 84));
          item.IconImage = "defaultVideoBig.png";
          item.IconImageBig = GetLocalImageFileName(provider.GetVideoImage(vi.Video.Id,84));
          item.Year = vi.Video.CopyrightYear;
          item.Duration = vi.Video.Duration;
          item.Rating = vi.Video.Rating;
          item.OnItemSelected += new MediaPortal.GUI.Library.GUIListItem.ItemSelectedHandler(item_OnItemSelected);
          DownloadImage(GetLocalImageFileName(provider.GetVideoImage(vi.Video.Id, 84)));
          item.MusicTag = vi;
          listControl.Add(item);
        }
      }
    }

    private void item_OnItemSelected(GUIListItem item, GUIControl parent)
    {
      VideoResponse vid = item.MusicTag as VideoResponse;
      if (vid != null)
      {
        if (File.Exists(GetLocalImageFileName(provider.GetArtistImage(vid.Artist.Id, 400))))
        {
          listControl.FilmstripView.InfoImageFileName = GetLocalImageFileName(provider.GetArtistImage(vid.Artist.Id, 400));
        }
        else
        {
          listControl.FilmstripView.InfoImageFileName = GetLocalImageFileName(vid.Image.Url);
        }
        SetLabels(vid, "Curent");
      }
    }

    private void SaveListState(bool clear)
    {
      if (listControl.ListView.ListItems.Count > 0)
      {
        NavigationStack.Push(new NavigationObject(listControl.ListView, GUIPropertyManager.GetProperty("#header.label"), listControl.SelectedListItemIndex));
      }
      if (clear)
      {
        GUIControl.ClearControl(GetID, listControl.GetID);
      }
    }
    

  }
}
